Pythonã®SocketServerã¢ãžã¥ãŒã«ã䜿çšããŠãå ç¢ã§ã¹ã±ãŒã©ãã«ãªãœã±ãããµãŒããŒãæ§ç¯ããæ¹æ³ãåŠã³ãŸããã³ã¢ã³ã³ã»ãããå®è·µçãªäŸãããã³è€æ°ã®ã¯ã©ã€ã¢ã³ããåŠçããããã®é«åºŠãªãã¯ããã¯ãæ¢æ±ããŸãã
ãœã±ãããµãŒããŒãã¬ãŒã ã¯ãŒã¯ïŒPythonã®SocketServerã¢ãžã¥ãŒã«ã®å®è·µã¬ã€ã
仿¥ã®çžäºæ¥ç¶ãããäžçã§ã¯ããœã±ããããã°ã©ãã³ã°ã¯ãç°ãªãã¢ããªã±ãŒã·ã§ã³ãšã·ã¹ãã éã®éä¿¡ãå¯èœã«ããäžã§éèŠãªåœ¹å²ãæãããŠããŸããPythonã®SocketServerã¢ãžã¥ãŒã«ã¯ããããã¯ãŒã¯ãµãŒããŒãäœæããããã®ç°¡ç¥åãããæ§é åãããæ¹æ³ãæäŸããåºç€ãšãªãè€éãã®å€ããæœè±¡åããŸãããã®ã¬ã€ãã§ã¯ããœã±ãããµãŒããŒãã¬ãŒã ã¯ãŒã¯ã®åºæ¬çãªæŠå¿µã«ã€ããŠèª¬æããPythonã§ã®SocketServerã¢ãžã¥ãŒã«ã®å®è·µçãªã¢ããªã±ãŒã·ã§ã³ã«çŠç¹ãåœãŠãŸããåºæ¬çãªãµãŒããŒèšå®ãè€æ°ã®ã¯ã©ã€ã¢ã³ãã®åæåŠçãããã³ç¹å®ã®ããŒãºã«é©ãããµãŒããŒã¿ã€ãã®éžæãªã©ãããŸããŸãªåŽé¢ãåãäžããŸããç°¡åãªãã£ããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããå Žåã§ããè€éãªåæ£ã·ã¹ãã ãæ§ç¯ããå Žåã§ããSocketServerãçè§£ããããšã¯ãPythonã§ã®ãããã¯ãŒã¯ããã°ã©ãã³ã°ãç¿åŸããããã®éèŠãªã¹ãããã§ãã
ãœã±ãããµãŒããŒã®çè§£
ãœã±ãããµãŒããŒã¯ãç¹å®ã®ããŒãã§çä¿¡ã¯ã©ã€ã¢ã³ãæ¥ç¶ããªãã¹ã³ããããã°ã©ã ã§ããã¯ã©ã€ã¢ã³ããæ¥ç¶ãããšããµãŒããŒã¯æ¥ç¶ãåãå
¥ããéä¿¡çšã®æ°ãããœã±ãããäœæããŸããããã«ããããµãŒããŒã¯è€æ°ã®ã¯ã©ã€ã¢ã³ããåæã«åŠçã§ããŸããPythonã®SocketServerã¢ãžã¥ãŒã«ã¯ããã®ãããªãµãŒããŒãæ§ç¯ããããã®ãã¬ãŒã ã¯ãŒã¯ãæäŸãããœã±ãã管çãšæ¥ç¶åŠçã®äœã¬ãã«ã®è©³çްãåŠçããŸãã
ã³ã¢ã³ã³ã»ãã
- ãœã±ãã: ãœã±ããã¯ããããã¯ãŒã¯äžã§å®è¡ãããŠãã2ã€ã®ããã°ã©ã éã®åæ¹åéä¿¡ãªã³ã¯ã®ãšã³ããã€ã³ãã§ããããã¯é»è©±ãžã£ãã¯ã«äŒŒãŠããŸããããããã°ã©ã ããœã±ããã«æ¥ç¶ããŠæ å ±ãéä¿¡ããå¥ã®ããã°ã©ã ãå¥ã®ãœã±ããã«æ¥ç¶ããŠæ å ±ãåä¿¡ããŸãã
- ããŒã: ããŒãã¯ããããã¯ãŒã¯æ¥ç¶ãéå§ããã³çµäºããä»®æ³ãã€ã³ãã§ããããã¯ãåäžã®ãã·ã³ã§å®è¡ãããŠããç°ãªãã¢ããªã±ãŒã·ã§ã³ãŸãã¯ãµãŒãã¹ãåºå¥ããæ°å€èå¥åã§ããããšãã°ãHTTPã¯éåžžããŒã80ã䜿çšããHTTPSã¯ããŒã443ã䜿çšããŸãã
- IPã¢ãã¬ã¹: IPïŒã€ã³ã¿ãŒããããããã³ã«ïŒã¢ãã¬ã¹ã¯ãã€ã³ã¿ãŒããããããã³ã«ã䜿çšããŠéä¿¡ããã³ã³ãã¥ãŒã¿ãŒãããã¯ãŒã¯ã«æ¥ç¶ãããåããã€ã¹ã«å²ãåœãŠãããæ°å€ã©ãã«ã§ãããããã¯ãŒã¯äžã®ããã€ã¹ãèå¥ããä»ã®ããã€ã¹ããã®ããã€ã¹ã«ããŒã¿ãéä¿¡ã§ããããã«ããŸããIPã¢ãã¬ã¹ã¯ãã€ã³ã¿ãŒãããäžã®ã³ã³ãã¥ãŒã¿ãŒã®éµäŸ¿ã¢ãã¬ã¹ã®ãããªãã®ã§ãã
- TCP vs. UDP: TCPïŒTransmission Control ProtocolïŒãšUDPïŒUser Datagram ProtocolïŒã¯ããããã¯ãŒã¯éä¿¡ã§äœ¿çšããã2ã€ã®åºæ¬çãªãã©ã³ã¹ããŒããããã³ã«ã§ããTCPã¯æ¥ç¶æåã§ãããä¿¡é Œæ§ãé«ããé åºä»ãããããšã©ãŒãã§ãã¯ãããããŒã¿ã®é ä¿¡ãæäŸããŸããUDPã¯ã³ãã¯ã·ã§ã³ã¬ã¹ã§ãããããé«éã§ããä¿¡é Œæ§ã®äœãé ä¿¡ãæäŸããŸããTCPãšUDPã®ã©ã¡ããéžæãããã¯ãã¢ããªã±ãŒã·ã§ã³ã®èŠä»¶ã«ãã£ãŠç°ãªããŸãã
Pythonã®SocketServerã¢ãžã¥ãŒã«ã®ç޹ä»
SocketServerã¢ãžã¥ãŒã«ã¯ãåºç€ãšãªããœã±ããAPIãžã®é«ã¬ãã«ã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããããšã«ãããPythonã§ã®ãããã¯ãŒã¯ãµãŒããŒã®äœæããã»ã¹ãç°¡çŽ åããŸãããœã±ãã管çã®è€éãã®å€ããæœè±¡åããéçºè
ãäœã¬ãã«ã®è©³çްã§ã¯ãªããã¢ããªã±ãŒã·ã§ã³ããžãã¯ã«éäžã§ããããã«ããŸãããã®ã¢ãžã¥ãŒã«ã¯ãTCPãµãŒããŒïŒTCPServerïŒãUDPãµãŒããŒïŒUDPServerïŒãªã©ãããŸããŸãªã¿ã€ãã®ãµãŒããŒãäœæããããã«äœ¿çšã§ããããã€ãã®ã¯ã©ã¹ãæäŸããŸãã
SocketServerã®äž»èŠã¯ã©ã¹
BaseServer:SocketServerã¢ãžã¥ãŒã«ã®ãã¹ãŠã®ãµãŒããŒã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹ãæ¥ç¶ããªãã¹ã³ãããããªã¯ãšã¹ããåŠçããããããªã©ãåºæ¬çãªãµãŒããŒã®åäœãå®çŸ©ããŸããTCPServer: TCPïŒTransmission Control ProtocolïŒãµãŒããŒãå®è£ ããBaseServerã®ãµãã¯ã©ã¹ãTCPã¯ãä¿¡é Œæ§ãé«ããé åºä»ãããããšã©ãŒãã§ãã¯ãããããŒã¿ã®é ä¿¡ãæäŸããŸããUDPServer: UDPïŒUser Datagram ProtocolïŒãµãŒããŒãå®è£ ããBaseServerã®ãµãã¯ã©ã¹ãUDPã¯ã³ãã¯ã·ã§ã³ã¬ã¹ã§ãããããé«éã§ããä¿¡é Œæ§ã®äœãããŒã¿äŒéãæäŸããŸããBaseRequestHandler: ãªã¯ãšã¹ããã³ãã©ãŒã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹ããªã¯ãšã¹ããã³ãã©ãŒã¯ãåã ã®ã¯ã©ã€ã¢ã³ããªã¯ãšã¹ãã®åŠçãæ åœããŸããStreamRequestHandler: TCPãªã¯ãšã¹ããåŠçããBaseRequestHandlerã®ãµãã¯ã©ã¹ãã¯ã©ã€ã¢ã³ããœã±ãããšã®éã§ããŒã¿ãã¹ããªãŒã ãšããŠèªã¿æžãããããã®äŸ¿å©ãªã¡ãœãããæäŸããŸããDatagramRequestHandler: UDPãªã¯ãšã¹ããåŠçããBaseRequestHandlerã®ãµãã¯ã©ã¹ãããŒã¿ã°ã©ã ïŒããŒã¿ã®ãã±ããïŒãéåä¿¡ããããã®ã¡ãœãããæäŸããŸãã
åçŽãªTCPãµãŒããŒã®äœæ
ãŸããçä¿¡æ¥ç¶ããªãã¹ã³ããåä¿¡ããããŒã¿ãã¯ã©ã€ã¢ã³ãã«ãšã³ãŒããã¯ããåçŽãªTCPãµãŒããŒãäœæããŸãããã®äŸã¯ãSocketServerã¢ããªã±ãŒã·ã§ã³ã®åºæ¬çãªæ§é ã瀺ããŠããŸãã
äŸïŒãšã³ãŒãµãŒããŒ
åºæ¬çãªãšã³ãŒãµãŒããŒã®ã³ãŒããæ¬¡ã«ç€ºããŸãã
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
"""
The request handler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print "{} wrote:".format(self.client_address[0])
print self.data
# just send back the same data you received.
self.request.sendall(self.data)
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
説æ:
SocketServerã¢ãžã¥ãŒã«ãã€ã³ããŒãããŸããSocketServer.BaseRequestHandlerããç¶æ¿ãããªã¯ãšã¹ããã³ãã©ãŒã¯ã©ã¹MyTCPHandlerãå®çŸ©ããŸããhandle()ã¡ãœããã¯ããªã¯ãšã¹ããã³ãã©ãŒã®ã³ã¢ã§ããã¯ã©ã€ã¢ã³ãããµãŒããŒã«æ¥ç¶ãããã³ã«åŒã³åºãããŸããhandle()ã¡ãœããå ã§ãself.request.recv(1024)ã䜿çšããŠã¯ã©ã€ã¢ã³ãããããŒã¿ãåä¿¡ããŸãããã®äŸã§ã¯ãåä¿¡ããæå€§ããŒã¿ã1024ãã€ãã«å¶éããŠããŸãã- ã¯ã©ã€ã¢ã³ãã®ã¢ãã¬ã¹ãšåä¿¡ããããŒã¿ãã³ã³ãœãŒã«ã«åºåããŸãã
self.request.sendall(self.data)ã䜿çšããŠãåä¿¡ããããŒã¿ãã¯ã©ã€ã¢ã³ãã«éãè¿ããŸããif __name__ == "__main__":ãããã¯ã§ãTCPServerã€ã³ã¹ã¿ã³ã¹ãäœæããlocalhostã¢ãã¬ã¹ãšããŒã9999ã«ãã€ã³ãããŸãã- 次ã«ã
server.serve_forever()ãåŒã³åºããŠãµãŒããŒãèµ·åããããã°ã©ã ãäžæããããŸã§å®è¡ãç¶ããŸãã
ãšã³ãŒãµãŒããŒã®å®è¡
ãšã³ãŒãµãŒããŒãå®è¡ããã«ã¯ãã³ãŒãããã¡ã€ã«ïŒäŸïŒecho_server.pyïŒã«ä¿åããã³ãã³ãã©ã€ã³ããå®è¡ããŸãã
python echo_server.py
ãµãŒããŒã¯ããŒã9999ã§æ¥ç¶ã®ãªãã¹ã³ãéå§ããŸããæ¬¡ã«ãtelnetãnetcatãªã©ã®ã¯ã©ã€ã¢ã³ãããã°ã©ã ã䜿çšããŠãµãŒããŒã«æ¥ç¶ã§ããŸããããšãã°ãnetcatã䜿çšããå ŽåïŒ
nc localhost 9999
netcatã¯ã©ã€ã¢ã³ãã«å
¥åããå
容ã¯ãã¹ãŠãµãŒããŒã«éä¿¡ããããšã³ãŒããã¯ãããŸãã
è€æ°ã®ã¯ã©ã€ã¢ã³ãã®åæåŠç
äžèšã®åºæ¬çãªãšã³ãŒãµãŒããŒã¯ãäžåºŠã«1ã€ã®ã¯ã©ã€ã¢ã³ãããåŠçã§ããŸãããæåã®ã¯ã©ã€ã¢ã³ãããŸã ãµãŒãã¹ãåããŠãããšãã«2çªç®ã®ã¯ã©ã€ã¢ã³ããæ¥ç¶ãããšã2çªç®ã®ã¯ã©ã€ã¢ã³ãã¯æåã®ã¯ã©ã€ã¢ã³ããåæããããŸã§åŸ ã€å¿ èŠããããŸããããã¯ãã»ãšãã©ã®çŸå®äžçã®ã¢ããªã±ãŒã·ã§ã³ã«ã¯çæ³çã§ã¯ãããŸãããè€æ°ã®ã¯ã©ã€ã¢ã³ããåæã«åŠçããã«ã¯ãã¹ã¬ãããŸãã¯ãã©ãŒã¯ã䜿çšã§ããŸããã¹ã¬ããåŠç
ã¹ã¬ããåŠçã«ãããè€æ°ã®ã¯ã©ã€ã¢ã³ããåãããã»ã¹å
ã§åæã«åŠçã§ããŸããåã¯ã©ã€ã¢ã³ãæ¥ç¶ã¯å¥ã®ã¹ã¬ããã§åŠçãããããããµãŒããŒã¯ä»ã®ã¯ã©ã€ã¢ã³ãããµãŒãã¹ãåããŠããéãæ°ããæ¥ç¶ã®ãªãã¹ã³ãç¶è¡ã§ããŸããSocketServerã¢ãžã¥ãŒã«ã¯ããµãŒããŒã¯ã©ã¹ãšæ··åããŠã¹ã¬ããåŠçãæå¹ã«ã§ããThreadingMixInã¯ã©ã¹ãæäŸããŸãã
äŸïŒã¹ã¬ããåããããšã³ãŒãµãŒããŒ
import SocketServer
import threading
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request.recv(1024)
cur_thread = threading.current_thread()
response = "{}: {}".format(cur_thread.name, data)
self.request.sendall(response)
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
ip, port = server.server_address
# Start a thread with the server -- that thread will then start one
# more thread for each request
server_thread = threading.Thread(target=server.serve_forever)
# Exit the server thread when the main thread terminates
server_thread.daemon = True
server_thread.start()
print "Server loop running in thread:", server_thread.name
# ... (Your main thread logic here, e.g., simulating client connections)
# For example, to keep the main thread alive:
# while True:
# pass # Or perform other tasks
server.shutdown()
説æ:
threadingã¢ãžã¥ãŒã«ãã€ã³ããŒãããŸããSocketServer.BaseRequestHandlerããç¶æ¿ããThreadedTCPRequestHandlerã¯ã©ã¹ãäœæããŸããhandle()ã¡ãœããã¯åã®äŸãšäŒŒãŠããŸãããå¿çã«çŸåšã®ã¹ã¬ããã®ååãå«ãŸããŠããŸããSocketServer.ThreadingMixInãšSocketServer.TCPServerã®äž¡æ¹ããç¶æ¿ããThreadedTCPServerã¯ã©ã¹ãäœæããŸãããã®ããã¯ã¹ã€ã³ã¯ããµãŒããŒã®ã¹ã¬ããåŠçãæå¹ã«ããŸããif __name__ == "__main__":ãããã¯ã§ãThreadedTCPServerã€ã³ã¹ã¿ã³ã¹ãäœæããå¥ã®ã¹ã¬ããã§èµ·åããŸããããã«ãããã¡ã€ã³ã¹ã¬ããã¯ããã¯ã°ã©ãŠã³ãã§ãµãŒããŒãå®è¡ãããŠããéãå®è¡ãç¶è¡ã§ããŸãã
ããã§ããã®ãµãŒããŒã¯è€æ°ã®ã¯ã©ã€ã¢ã³ãæ¥ç¶ãåæã«åŠçã§ããŸãã忥ç¶ã¯å¥ã®ã¹ã¬ããã§åŠçãããããããµãŒããŒã¯è€æ°ã®ã¯ã©ã€ã¢ã³ãã«åæã«å¿çã§ããŸãã
ãã©ãŒã¯
ãã©ãŒã¯ã¯ãè€æ°ã®ã¯ã©ã€ã¢ã³ããåæã«åŠçãããã1ã€ã®æ¹æ³ã§ããæ°ããã¯ã©ã€ã¢ã³ãæ¥ç¶ãåä¿¡ãããšããµãŒããŒã¯æ°ããããã»ã¹ããã©ãŒã¯ããŠæ¥ç¶ãåŠçããŸããåããã»ã¹ã«ã¯ç¬èªã®ã¡ã¢ãªãŒç©ºéããããããããã»ã¹ã¯äºãã«åé¢ãããŠããŸããSocketServerã¢ãžã¥ãŒã«ã¯ããµãŒããŒã¯ã©ã¹ãšæ··åããŠãã©ãŒã¯ãæå¹ã«ã§ããForkingMixInã¯ã©ã¹ãæäŸããŸããæ³šïŒãã©ãŒã¯ã¯éåžžãUnixã©ã€ã¯ã·ã¹ãã ïŒLinuxãmacOSïŒã§äœ¿çšãããWindowsç°å¢ã§ã¯äœ¿çšã§ããªãããé©åã§ã¯ãªãå ŽåããããŸãã
äŸïŒãã©ãŒã¯ãšã³ãŒãµãŒããŒ
import SocketServer
import os
class ForkingTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request.recv(1024)
pid = os.getpid()
response = "PID {}: {}".format(pid, data)
self.request.sendall(response)
class ForkingTCPServer(SocketServer.ForkingMixIn, SocketServer.TCPServer):
pass
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = ForkingTCPServer((HOST, PORT), ForkingTCPRequestHandler)
ip, port = server.server_address
server.serve_forever()
説æ:
osã¢ãžã¥ãŒã«ãã€ã³ããŒãããŸããSocketServer.BaseRequestHandlerããç¶æ¿ããForkingTCPRequestHandlerã¯ã©ã¹ãäœæããŸããhandle()ã¡ãœããã«ã¯ãå¿çã«ããã»ã¹IDïŒPIDïŒãå«ãŸããŠããŸããSocketServer.ForkingMixInãšSocketServer.TCPServerã®äž¡æ¹ããç¶æ¿ããForkingTCPServerã¯ã©ã¹ãäœæããŸãããã®ããã¯ã¹ã€ã³ã¯ããµãŒããŒã®ãã©ãŒã¯ãæå¹ã«ããŸããif __name__ == "__main__":ãããã¯ã§ãForkingTCPServerã€ã³ã¹ã¿ã³ã¹ãäœæããserver.serve_forever()ã䜿çšããŠèµ·åããŸããåã¯ã©ã€ã¢ã³ãæ¥ç¶ã¯å¥ã®ããã»ã¹ã§åŠçãããŸãã
ã¯ã©ã€ã¢ã³ãããã®ãµãŒããŒã«æ¥ç¶ãããšããµãŒããŒã¯æ°ããããã»ã¹ããã©ãŒã¯ããŠæ¥ç¶ãåŠçããŸããåããã»ã¹ã«ã¯ç¬èªã®PIDããããããæ¥ç¶ãç°ãªãããã»ã¹ã«ãã£ãŠåŠçãããŠããããšã確èªã§ããŸãã
ã¹ã¬ããåŠçãšãã©ãŒã¯ã®éžæ
ã¹ã¬ããåŠçãšãã©ãŒã¯ã®éžæã¯ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãã¢ããªã±ãŒã·ã§ã³ã®æ§è³ªãå©çšå¯èœãªãªãœãŒã¹ãªã©ãããã€ãã®èŠå ã«ãã£ãŠç°ãªããŸããäž»ãªèæ ®äºé ã®æŠèŠã次ã«ç€ºããŸãã
- ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ïŒãã©ãŒã¯ã¯éåžžãUnixã©ã€ã¯ã·ã¹ãã ã§æšå¥šãããã¹ã¬ããåŠçã¯Windowsã§ããäžè¬çã§ãã
- ãªãœãŒã¹æ¶è²»éïŒåããã»ã¹ã«ã¯ç¬èªã®ã¡ã¢ãªãŒç©ºéãããããããã©ãŒã¯ã¯ã¹ã¬ããåŠçãããå€ãã®ãªãœãŒã¹ãæ¶è²»ããŸããã¹ã¬ããåŠçã¯ã¡ã¢ãªãŒç©ºéãå ±æãããããããå¹ççã§ãããç«¶åç¶æ ããã®ä»ã®åæå®è¡ã®åé¡ãåé¿ããããã«æ éãªåæãå¿ èŠã§ãã
- è€éãïŒç¹ã«å ±æãªãœãŒã¹ãæ±ãå Žåãã¹ã¬ããåŠçã¯ãã©ãŒã¯ãããå®è£ ãšãããã°ãè€éã«ãªãå¯èœæ§ããããŸãã
- ã¹ã±ãŒã©ããªãã£ïŒãã©ãŒã¯ã¯å Žåã«ãã£ãŠã¯ã¹ã¬ããåŠçãããåªããã¹ã±ãŒãªã³ã°ãå¯èœã§ããè€æ°ã®CPUã³ã¢ããã广çã«å©çšã§ããããã§ãããã ããããã»ã¹ã®äœæãšç®¡çã®ãªãŒããŒãããã«ãã£ãŠãã¹ã±ãŒã©ããªãã£ãå¶éãããå¯èœæ§ããããŸãã
äžè¬ã«ãUnixã©ã€ã¯ã·ã¹ãã ã§åçŽãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããå Žåã¯ããã©ãŒã¯ãè¯ãéžæãããããŸãããããè€éãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããå ŽåããŸãã¯Windowsãã¿ãŒã²ããã«ããå Žåã¯ãã¹ã¬ããåŠçãããé©åãããããŸãããç°å¢ã®ãªãœãŒã¹å¶çŽãšãã¢ããªã±ãŒã·ã§ã³ã®æœåšçãªã¹ã±ãŒã©ããªãã£èŠä»¶ãèæ ®ããããšãéèŠã§ããé«åºŠã«ã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ã®å Žåã¯ã`asyncio`ã®ãããªéåæãã¬ãŒã ã¯ãŒã¯ãæ€èšããŠãã ãããããã«ãããããã©ãŒãã³ã¹ãšãªãœãŒã¹ã®äœ¿çšçãåäžããŸãã
åçŽãªUDPãµãŒããŒã®äœæ
UDPïŒUser Datagram ProtocolïŒã¯ãTCPãããé«éã§ããä¿¡é Œæ§ã®äœãããŒã¿äŒéãæäŸããã³ãã¯ã·ã§ã³ã¬ã¹ãããã³ã«ã§ããUDPã¯ãã¹ããªãŒãã³ã°ã¡ãã£ã¢ããªã³ã©ã€ã³ã²ãŒã ãªã©ãä¿¡é Œæ§ãããé床ãéèŠãªã¢ããªã±ãŒã·ã§ã³ã§ãã䜿çšãããŸããSocketServerã¢ãžã¥ãŒã«ã¯ãUDPãµãŒããŒãäœæããããã®UDPServerã¯ã©ã¹ãæäŸããŸãã
äŸïŒUDPãšã³ãŒãµãŒããŒ
import SocketServer
class MyUDPHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request[0].strip()
socket = self.request[1]
print "{} wrote:".format(self.client_address[0])
print data
socket.sendto(data, self.client_address)
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
server.serve_forever()
説æ:
MyUDPHandlerã¯ã©ã¹ã®handle()ã¡ãœããã¯ãã¯ã©ã€ã¢ã³ãããããŒã¿ãåä¿¡ããŸããTCPãšã¯ç°ãªããUDPããŒã¿ã¯ããŒã¿ã°ã©ã ïŒããŒã¿ã®ãã±ããïŒãšããŠåä¿¡ãããŸããself.request屿§ã¯ãããŒã¿ãšãœã±ãããå«ãã¿ãã«ã§ããself.request[0]ã䜿çšããŠããŒã¿ãæœåºããself.request[1]ã䜿çšããŠãœã±ãããæœåºããŸããsocket.sendto(data, self.client_address)ã䜿çšããŠãåä¿¡ããããŒã¿ãã¯ã©ã€ã¢ã³ãã«éãè¿ããŸãã
ãã®ãµãŒããŒã¯ãã¯ã©ã€ã¢ã³ãããUDPããŒã¿ã°ã©ã ãåä¿¡ããéä¿¡è ã«ãšã³ãŒããã¯ããŸãã
é«åºŠãªãã¯ããã¯
ç°ãªãããŒã¿åœ¢åŒã®åŠç
å€ãã®çŸå®äžçã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãJSONãXMLãProtocol Buffersãªã©ãç°ãªãããŒã¿åœ¢åŒãåŠçããå¿
èŠããããŸããPythonã®çµã¿èŸŒã¿ã¢ãžã¥ãŒã«ãŸãã¯ãµãŒãããŒãã£ã©ã€ãã©ãªã䜿çšããŠãããŒã¿ãã·ãªã¢ã«åããã³ãã·ãªã¢ã«åã§ããŸããããšãã°ãjsonã¢ãžã¥ãŒã«ã䜿çšããŠJSONããŒã¿ãåŠçã§ããŸãã
import SocketServer
import json
class JSONTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
try:
data = self.request.recv(1024).strip()
json_data = json.loads(data)
print "Received JSON data:", json_data
# Process the JSON data
response_data = {"status": "success", "message": "Data received"}
response_json = json.dumps(response_data)
self.request.sendall(response_json)
except ValueError as e:
print "Invalid JSON data received: {}".format(e)
self.request.sendall(json.dumps({"status": "error", "message": "Invalid JSON"}))
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), JSONTCPHandler)
server.serve_forever()
ãã®äŸã§ã¯ãã¯ã©ã€ã¢ã³ãããJSONããŒã¿ãåä¿¡ããjson.loads()ã䜿çšããŠè§£æããåŠçããjson.dumps()ã䜿çšããŠJSONå¿çãã¯ã©ã€ã¢ã³ãã«éãè¿ããŸããç¡å¹ãªJSONããŒã¿ããã£ããããããã®ãšã©ãŒåŠçãå«ãŸããŠããŸãã
èªèšŒã®å®è£
ã»ãã¥ã¢ãªã¢ããªã±ãŒã·ã§ã³ã®å Žåãã¯ã©ã€ã¢ã³ãã®IDãæ€èšŒããããã«èªèšŒãå®è£ ããå¿ èŠããããŸããããã¯ããŠãŒã¶ãŒå/ãã¹ã¯ãŒãèªèšŒãAPIããŒãããžã¿ã«èšŒææžãªã©ãããŸããŸãªæ¹æ³ã䜿çšããŠè¡ãããšãã§ããŸãããŠãŒã¶ãŒå/ãã¹ã¯ãŒãèªèšŒã®ç°¡ç¥åãããäŸã次ã«ç€ºããŸãã
import SocketServer
import hashlib
# Replace with a secure way to store passwords (e.g., using bcrypt)
USER_CREDENTIALS = {
"user1": "password123",
"user2": "secure_password"
}
class AuthTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
# Authentication logic
username = self.request.recv(1024).strip()
password = self.request.recv(1024).strip()
if username in USER_CREDENTIALS and USER_CREDENTIALS[username] == password:
print "User {} authenticated successfully".format(username)
self.request.sendall("Authentication successful")
# Proceed with handling the client request
# (e.g., receive further data and process it)
else:
print "Authentication failed for user {}".format(username)
self.request.sendall("Authentication failed")
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), AuthTCPHandler)
server.serve_forever()
éèŠãªã»ãã¥ãªãã£ã«é¢ããæ³šæïŒäžèšã®äŸã¯ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã®ã¿ãç®çãšããŠãããå®å šã§ã¯ãããŸããããã¹ã¯ãŒãããã¬ãŒã³ããã¹ãã§ä¿åããªãã§ãã ããã匷åãªãã¹ã¯ãŒãããã·ã¥ã¢ã«ãŽãªãºã ïŒbcryptãArgon2ãªã©ïŒã䜿çšããŠããã¹ã¯ãŒããããã·ã¥ããŠããä¿åããŠãã ãããããã«ãæ¬çªç°å¢ã§ã¯ãOAuth 2.0ãJWTïŒJSON Web TokensïŒãªã©ã®ããå ç¢ãªèªèšŒã¡ã«ããºã ã®äœ¿çšãæ€èšããŠãã ããã
ãã®ã³ã°ãšãšã©ãŒåŠç
é©åãªãã®ã³ã°ãšãšã©ãŒåŠçã¯ããµãŒããŒã®ãããã°ãšä¿å®ã«äžå¯æ¬ ã§ããPythonã®loggingã¢ãžã¥ãŒã«ã䜿çšããŠãã€ãã³ãããšã©ãŒãããã³ãã®ä»ã®é¢é£æ
å ±ãèšé²ããŸããäŸå€ãé©åã«åŠçãããµãŒããŒãã¯ã©ãã·ã¥ããã®ãé²ãããã«ãå
æ¬çãªãšã©ãŒåŠçãå®è£
ããŸããåé¡ã广çã«èšºæããããã«ãåžžã«ååãªæ
å ±ãèšé²ããŠãã ããã
import SocketServer
import logging
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
class LoggingTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
try:
data = self.request.recv(1024).strip()
logging.info("Received data from {}: {}".format(self.client_address[0], data))
self.request.sendall(data)
except Exception as e:
logging.exception("Error handling request from {}: {}".format(self.client_address[0], e))
self.request.sendall("Error processing request")
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), LoggingTCPHandler)
server.serve_forever()
ãã®äŸã§ã¯ãçä¿¡ãªã¯ãšã¹ãããã³ãªã¯ãšã¹ãåŠçäžã«çºçãããšã©ãŒã«é¢ããæ
å ±ãèšé²ããããã«ãã®ã³ã°ãæ§æããŸããlogging.exception()ã¡ãœããã¯ããããã°ã«åœ¹ç«ã€å¯èœæ§ãããå®å
šãªã¹ã¿ãã¯ãã¬ãŒã¹ãšãšãã«äŸå€ããã°ã«èšé²ããããã«äœ¿çšãããŸãã
SocketServerã®ä»£æ¿
SocketServerã¢ãžã¥ãŒã«ã¯ãœã±ããããã°ã©ãã³ã°ãåŠã¶ããã®è¯ãåºçºç¹ã§ãããç¹ã«é«æ§èœã§ã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ã®å Žåãããã€ãã®å¶éããããŸããäžè¬çãªä»£æ¿ææ®µã次ã«ç€ºããŸãã
- asyncio: Pythonã®çµã¿èŸŒã¿éåæI / Oãã¬ãŒã ã¯ãŒã¯ã
asyncioã¯ãã³ã«ãŒãã³ãšã€ãã³ãã«ãŒãã䜿çšããŠãè€æ°ã®åææ¥ç¶ãããå¹ççã«åŠçããæ¹æ³ãæäŸããŸããé«ãåæå®è¡æ§ãå¿ èŠãªææ°ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãäžè¬çã«æšå¥šãããŸãã - Twisted: Pythonã§èšè¿°ãããã€ãã³ãããªãã³ãããã¯ãŒãã³ã°ãšã³ãžã³ãTwistedã¯ãããŸããŸãªãããã³ã«ãåæå®è¡ã¢ãã«ã®ãµããŒããªã©ããããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®è±å¯ãªæ©èœã»ãããæäŸããŸãã
- Tornado: Python Webãã¬ãŒã ã¯ãŒã¯ããã³éåæãããã¯ãŒã¯ã©ã€ãã©ãªãTornadoã¯ã倿°ã®åææ¥ç¶ãåŠçããããã«èšèšãããŠããããªã¢ã«ã¿ã€ã Webã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ã«ãã䜿çšãããŸãã
- ZeroMQ: 髿§èœéåæã¡ãã»ãŒãžã³ã°ã©ã€ãã©ãªãZeroMQã¯ã忣ã·ã¹ãã ãšã¡ãã»ãŒãžãã¥ãŒãæ§ç¯ããããã®ã·ã³ãã«ã§å¹ççãªæ¹æ³ãæäŸããŸãã
çµè«
Pythonã®SocketServerã¢ãžã¥ãŒã«ã¯ããããã¯ãŒã¯ããã°ã©ãã³ã°ãžã®è²Žéãªå
¥éãšãªããåºæ¬çãªãœã±ãããµãŒããŒãæ¯èŒçç°¡åã«æ§ç¯ã§ããŸãããœã±ãããTCP / UDPãããã³ã«ãããã³SocketServerã¢ããªã±ãŒã·ã§ã³ã®æ§é ã®åºæ¬æŠå¿µãçè§£ããããšã¯ããããã¯ãŒã¯ããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ãéçºããäžã§éåžžã«éèŠã§ããSocketServerã¯ãç¹ã«é«ãã¹ã±ãŒã©ããªãã£ãŸãã¯ããã©ãŒãã³ã¹ãå¿
èŠãšããã·ããªãªã«ã¯é©ããŠããªãå ŽåããããŸãããããé«åºŠãªãããã¯ãŒã¯æè¡ãåŠç¿ããasyncioãTwistedãTornadoãªã©ã®ä»£æ¿ãã¬ãŒã ã¯ãŒã¯ãæ¢çŽ¢ããããã®åŒ·åãªåºç€ãšããŠæ©èœããŸãããã®ã¬ã€ãã§æŠèª¬ãããŠããååãç¿åŸããããšã§ãå¹
åºããããã¯ãŒã¯ããã°ã©ãã³ã°ã®èª²é¡ã«åãçµãæºåãæŽããŸãã
åœéçãªèæ ®äºé
ã°ããŒãã«ãªãªãŒãã£ãšã³ã¹åãã®ãœã±ãããµãŒããŒã¢ããªã±ãŒã·ã§ã³ãéçºããå Žåã¯ã次ã®åœéåïŒi18nïŒããã³ããŒã«ãªãŒãŒã·ã§ã³ïŒl10nïŒã®èŠçŽ ãèæ ®ããããšãéèŠã§ãã
- æåãšã³ã³ãŒãã£ã³ã°ïŒãµãŒããŒãUTF-8ãªã©ã®ããŸããŸãªæåãšã³ã³ãŒãã£ã³ã°ããµããŒãããŠãç°ãªãèšèªããã®ããã¹ãããŒã¿ãæ£ããåŠçã§ããããã«ããŸããå éšã§Unicodeã䜿çšããããŒã¿ãã¯ã©ã€ã¢ã³ãã«éä¿¡ãããšãã«é©åãªãšã³ã³ãŒãã£ã³ã°ã«å€æããŸãã
- ã¿ã€ã ãŸãŒã³ïŒã¿ã€ã ã¹ã¿ã³ããåŠçããããã€ãã³ããã¹ã±ãžã¥ãŒã«ããããããšãã¯ãã¿ã€ã ãŸãŒã³ã«æ³šæããŠãã ããã
pytzã®ãããªã¿ã€ã ãŸãŒã³å¯Ÿå¿ã©ã€ãã©ãªã䜿çšããŠãç°ãªãã¿ã€ã ãŸãŒã³éã倿ããŸãã - æ°å€ãšæ¥ä»ã®æžåŒèšå®ïŒãã±ãŒã«å¯Ÿå¿ã®æžåŒèšå®ã䜿çšããŠãç°ãªãå°åã«å¯ŸããŠæ£ãã圢åŒã§æ°å€ãšæ¥ä»ã衚瀺ããŸããPythonã®
localeã¢ãžã¥ãŒã«ã¯ããã®ç®çã«äœ¿çšã§ããŸãã - èšèªç¿»èš³ïŒãµãŒããŒã®ã¡ãã»ãŒãžãšãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãããŸããŸãªèšèªã«ç¿»èš³ããŠãããå¹ åºããŠãŒã¶ãŒãã¢ã¯ã»ã¹ã§ããããã«ããŸãã
- é貚åŠçïŒéèååŒãæ±ãå Žåã¯ããµãŒããŒãç°ãªãé貚ããµããŒãããæ£ããçºæ¿ã¬ãŒãã䜿çšããŠããããšã確èªããŸãã
- æ³çããã³èŠå¶éµå®ïŒããŸããŸãªåœã§ã®ãµãŒããŒã®éçšã«é©çšãããå¯èœæ§ã®ããæ³çãŸãã¯èŠå¶äžã®èŠä»¶ïŒããŒã¿ãã©ã€ãã·ãŒæ³ïŒGDPRãªã©ïŒãªã©ïŒã«æ³šæããŠãã ããã
ãããã®åœéåã®èæ ®äºé ã«å¯ŸåŠããããšã«ãããã°ããŒãã«ãªãªãŒãã£ãšã³ã¹ã«ãšã£ãŠã¢ã¯ã»ã¹ããããããŠãŒã¶ãŒãã¬ã³ããªãŒãªãœã±ãããµãŒããŒã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸãã